<?php
namespace admin\action;

use common\service\CommonService;
use herosphp\bean\Beans;
use herosphp\core\Controller;
use herosphp\core\WebApplication;
use herosphp\http\HttpRequest;
use herosphp\session\Session;
use herosphp\utils\AjaxResult;
use herosphp\utils\ArrayUtils;
use herosphp\utils\ModelTransformUtils;
use herosphp\utils\Page;
use herosphp\web\WebUtils;

define('COM_ERR_MSG', '(⊙o⊙) 系统出了小差！');

/**
 * 模块通用 Action
 * @author          yangjian<yangjian102621@gmail.com>
 */
abstract class CommonAction extends Controller {
	//消息类型常量 info warning success danger
	const MESSAGE_ERROR = 'danger'; //严重错误
	const MESSAGE_WARN = 'warning'; //警告
	const MESSAGE_INFO = 'info'; //普通提示
	const MESSAGE_SUCESS = 'success'; //操作成功

	const COM_ERR_MSG = '(⊙o⊙) 系统出了小差.'; //通用报错类型
	const NO_RECORDS = '(⊙o⊙) 找不到对应的记录.'; //找不到记录
	const NO_PERMISSION = 'O(∩_∩)O 对不起，你没有操作权限， 请联系管理员添加权限.'; //没有权限

	//页码
	protected $page = 1;

	//每页记录数
	protected $pagesize = 15;

	//查询条件(array)
	protected $conditions;

	//排序方式
	protected $order = array('addtime' => -1);

	//分组字段
	protected $group;

	/**
	 * 分组条件
	 * @var string|array
	 */
	protected $having;

	/**
	 * 查询字段
	 * @var string|array
	 */
	protected $fields;

	/**
	 * 管理员用户
	 * @var \admin\models\Manager
	 */
	public $loginUser;

	/**
	 * Beans服务的key
	 * @var string
	 */
	protected $serviceBean;

	//action名称
	protected $actionTitle;

	public function __construct()
	{
		parent::__construct();

		//判断登陆
		Session::start();
		$managerService = Beans::get('admin.manager.service');
		if ( !$managerService->isLogin() ) {
			if ( strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) {
				AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, LANG('NOT_LOGIN'));
			} else {
				location('/admin/login/index/?url='.urlencode($_SERVER['REQUEST_URI']));
			}
		}

		$this->loginUser = ModelTransformUtils::map2Model('admin\models\Manager', $managerService->getLoginManager());
		$request = WebApplication::getInstance()->getHttpRequest();
		$module = $request->getModule();
		$action = $request->getAction();
		$method = $request->getMethod();
		if ( !$this->loginUser->hasPermission("{$module}/{$action}/{$method}") ) {
			//判断请求的类型,如果是ajax请求则使用ajax返回
			if ( strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) {
				AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, self::NO_PERMISSION);
			} else {
				//location('/admin/index/error/?type=danger&message='.base64_encode(self::NO_PERMISSION));
				location('/admin/index/error/?type=danger&message='.self::NO_PERMISSION);

			}
		}
		$this->assign('loginUser', $this->loginUser);



		$this->assign("noRecords", "暂无数据");

		$this->assign("index_url", "/{$module}/{$action}/index");
		$this->assign("insert_url", "/{$module}/{$action}/insert");
		$this->assign("edit_url", "/{$module}/{$action}/edit");
		$this->assign("add_url", "/{$module}/{$action}/add");
		$this->assign("update_url", "/{$module}/{$action}/update");
		$this->assign("delete_url", "/{$module}/{$action}/delete");
	}

	/**
	 * 首页列表
	 * @param HttpRequest $request
	 */
	public function index( HttpRequest $request ) {

		$this->page = $request->getParameter('page', 'intval');
		$this->pagesize = $request->getParameter('pagesize', 'intval');
		if ( $this->page <=0 ) $this->page = 1;
		if ( $this->pagesize <=0 ) $this->pagesize = 15;

		$service = Beans::get($this->getServiceBean());
		$total = $service->count($this->getConditions());
		$items = $service->where($this->getConditions())
			->field($this->getFields())
			->sort($this->getOrder())
			->limit($this->getPage(), $this->getPagesize())
			->group($this->getGroup())
			->having($this->getHaving())->find();

		$this->generatePageMenu($total);
		$this->assign('items', $items);
	}

	/**
	 * 生成分页菜单
	 * @param $total
	 */
	protected function generatePageMenu($total) {

		//初始化分页类
		$pageHandler = new Page($total, $this->getPagesize(), $this->getPage(), 3);

		//获取分页数据
		$pageData = $pageHandler->getPageData(DEFAULT_PAGE_STYLE, true);
		//组合分页HTML代码
		if ( $pageData ) {
			$pagemenu = '<ul class="pagination">';
			$pagemenu .= '<li class="form-inline"><span>每页：<select class="form-control input-sm" id="per-pagesize">';
			foreach ( getConfig('admin_pagesize_options') as $v ) {
				if ( $v == $this->pagesize ) {
					$pagemenu .= '<option value="'.$v.'" selected>'.$v.'</option>';
				} else {
					$pagemenu .= '<option value="'.$v.'">'.$v.'</option>';
				}
			}
			$pagemenu .= '</select> 条</span></li>';
			$pagemenu .= '<li class="disabled"><a href="#">共'.$total.'条</a></li> ';
			$pagemenu .= '<li><a href="'.$pageData['first'].'">首页</a></li> ';
			$pagemenu .= '<li><a href="'.$pageData['prev'].'">上一页</a></li> ';
			foreach ( $pageData['list'] as $key => $value ) {
				if ( $key == $this->page ) {
					$pagemenu .= '<li class="active"><a href="#fakelink">'.$key.'</a></li> ';
				} else {
					$pagemenu .= '<li><a href="'.$value.'">'.$key.'</a></li> ';
				}
			}
			$pagemenu .= '<li><a href="'.$pageData['next'].'">下一页</a></li> ';
			$pagemenu .= '<li><a href="'.$pageData['last'].'">尾页</a></li> ';
			$pagemenu .= '</ul>';
		}

		$this->assign('pagemenu', $pagemenu);

	}

	/**
	 * 编辑操作
	 * @param HttpRequest $request
	 * @return void
	 */
	public function edit(HttpRequest $request) {

		$id = $request->getParameter('id', 'trim');
		if ( empty($id) ) {
			$this->showMessage('danger', self::NO_RECORDS);
			return;
		}
		$service = Beans::get($this->getServiceBean());
		$item = $service->getItem($id);
		$this->assign('item', $item);
	}

	/**
	 * 插入数据
	 * @param array $data
	 * @param $callback 回调函数
	 */
	protected function __insert(array $data, $callback=null) {

		$service = Beans::get($this->getServiceBean());
		$data['addtime'] = date('Y-m-d H:i:s');
		$data['updatetime'] = date('Y-m-d H:i:s');

		if ( $service->add($data) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			//记录操作日志
			$request = WebApplication::getInstance()->getHttpRequest();
			$request->addParameter('logmessage', "添加 {$this->actionTitle} [{$this->getOptobjByData($data)}]");
			AjaxResult::ajaxSuccessResult();
		} else {
			$message = WebApplication::getInstance()->getAppError()->getMessage();
			if ( !$message ) $message = "开通失败.";
			AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, $message);
		}
	}

	/**
	 * 更新数据
	 * @param array $data
	 * @param $id
	 * @param $callback 回调函数
	 */
	protected function __update(array $data, $id, $callback=null) {

		if ( empty($data) || empty($id) ) AjaxResult::ajaxFailtureResult();

		$data['updatetime'] = date('Y-m-d H:i:s');

		$service = Beans::get($this->getServiceBean());
		if ( $service->update($data, $id) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			//记录操作日志
			$request = WebApplication::getInstance()->getHttpRequest();
			$request->addParameter('logmessage', "更新 {$this->actionTitle} [{$this->getOptobjById($id)}]");
			AjaxResult::ajaxSuccessResult();
		} else {
			AjaxResult::ajaxFailtureResult();
		}

	}

	/**
	 * 快速保存
	 * @param HttpRequest $request
	 */
	public function quicksave( HttpRequest $request, $callback=null) {

		$hids = $request->getParameter('hids');
		$datas = $request->getParameter('data');
		$service = Beans::get($this->getServiceBean());
		$counter = 0;
		// 保存数据
		foreach ( $hids as $key => $id ) {
			$datas[$key]['updatetime'] = date('Y-m-d H:i:s');
			if ( $service->update($datas[$key], $id) ) {
				$counter++;
			}
		}

		//全部数据保存成功，则该操作成功
		if ( $counter == count($hids) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			//保存操作日志
			$request->addParameter('logmessage', "批量保存了 ".$this->actionTitle."， IDS ： [".implode(',', $hids)."]");
			AjaxResult::ajaxResult(AjaxResult::OP_SUCCESS, '保存成功！');
		} else {
			AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, '保存失败！');
		}
	}

	/**
	 * 设置某个字段的值
	 * @param HttpRequest $request
	 */
	public function set(HttpRequest $request, $callback=null) {
		$field = $request->getParameter('field', 'trim');
		$value = $request->getParameter('value', 'trim');
		$id = $request->getParameter('id', 'trim');

		if ( empty($id) || empty($field) ) {
			AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, self::NO_RECORDS);
		}
		$service = Beans::get($this->getServiceBean());
		if ( $service->set($field, $value, $id) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			//记录操作日志
			if ( $value == 1 ) $opt = '启用';
			else $opt = '禁用';

			$request->addParameter('logmessage', $opt.$this->actionTitle." [{$this->getOptobjById($id)}] ");
			AjaxResult::ajaxSuccessResult();
		} else {
			AjaxResult::ajaxFailtureResult();
		}
	}

	/**
	 * 批量设置某个字段的值
	 * @param HttpRequest $request
	 */
	public function sets(HttpRequest $request, $callback=null) {
		$field = $request->getParameter('field', 'trim');
		$value = $request->getParameter('value', 'trim');
		$ids = $request->getParameter('ids');

		if ( empty($ids) || empty($field) ) {
			AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, self::NO_RECORDS);
		}
		$service = Beans::get($this->getServiceBean());
		if ( $service->sets($field, $value, array('id' => array('$in' => $ids))) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			AjaxResult::ajaxSuccessResult();
		} else {
			AjaxResult::ajaxFailtureResult();
		}
	}

	/**
	 * 删除单条数据
	 * @param HttpRequest $request
	 */
	public function delete( HttpRequest $request, $callback=null ) {

		$id = $request->getParameter('id', 'trim');
		if ( empty($id) ) AjaxResult::ajaxResult('error', self::NO_RECORDS);

		$service = Beans::get($this->getServiceBean());
		$optObj = $this->getOptobjById($id);
		if ( $service->delete($id) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			$request->addParameter('logmessage', "删除 {$this->actionTitle} [{$optObj}]");
			AjaxResult::ajaxSuccessResult();
		} else {
			AjaxResult::ajaxFailtureResult();
		}
	}

	/**
	 * 批量删除数据
	 * @param HttpRequest $request
	 */
	public function deletes( HttpRequest $request, $callback ) {

		$ids = $request->getParameter('ids');
		if ( empty($ids) ) AjaxResult::ajaxResult(AjaxResult::OP_FAILURE, '请至少选择一条记录');

		$service = Beans::get($this->getServiceBean());
		if ( $service->deletes(array('id' => array('$in' => $ids))) ) {
			if ( !is_null($callback) ) {
				call_user_func($callback, $service);
			}
			AjaxResult::ajaxSuccessResult();
		} else {
			AjaxResult::ajaxFailtureResult();
		}
	}

	/**
	 * 检验某个字段的值是否在数据库中存在，用于保持某个字段的唯一性
	 * @param $field
	 * @param $value
	 * @return bool
	 */
	public function exists(HttpRequest $request) {

		$field = $request->getParameter('field', 'trim');
		$value = $request->getParameter('value', 'trim');
		$service = Beans::get($this->getServiceBean());
		if ( $service->getItem(array($field => $value)) ) {
			AjaxResult::ajaxSuccessResult(); //已存在
		} else {
			AjaxResult::ajaxFailtureResult();
		}
	}

	/**
	 * 信息显示模板
	 * @param $type 消息类型 info warnning success danger
	 * @param $message
	 * @param $url
	 */
	public function showMessage( $type, $message, $url ) {

		$this->assign('messageType', $type);
		$this->assign('message', $message);
		$this->assign('gotoUrl', $url);
		$this->setView('inc/message');

	}

	//404页面
	public function page404() {
		$this->setView('inc/404');
	}

	//500页面
	public function page500() {
		$this->setView('inc/500');
	}

	/**
	 * @param array|string $conditions
	 */
	protected function setConditions($conditions)
	{
		$this->conditions = $conditions;
	}

	/**
	 * @return array|string
	 */
	protected function getConditions()
	{
		return $this->conditions;
	}

	/**
	 * @param array|string $fields
	 */
	protected function setFields($fields)
	{
		$this->fields = $fields;
	}

	/**
	 * @return array|string
	 */
	protected function getFields()
	{
		return $this->fields;
	}

	/**
	 * @param string $group
	 */
	protected function setGroup($group)
	{
		$this->group = $group;
	}

	/**
	 * @return string
	 */
	protected function getGroup()
	{
		return $this->group;
	}

	/**
	 * @param array|string $having
	 */
	protected function setHaving($having)
	{
		$this->having = $having;
	}

	/**
	 * @return array|string
	 */
	protected function getHaving()
	{
		return $this->having;
	}

	/**
	 * @param array|string $order
	 */
	protected function setOrder($order)
	{
		$this->order = $order;
	}

	/**
	 * @return array|string
	 */
	protected function getOrder()
	{
		return $this->order;
	}

	/**
	 * @param int $page
	 */
	protected function setPage($page)
	{
		$this->page = $page;
	}

	/**
	 * @return int
	 */
	protected function getPage()
	{
		return $this->page;
	}

	/**
	 * @param int $pagesize
	 */
	protected function setPagesize($pagesize)
	{
		$this->pagesize = $pagesize;
	}

	/**
	 * @return int
	 */
	protected function getPagesize()
	{
		return $this->pagesize;
	}

	/**
	 * @param string $serviceBean
	 */
	protected function setServiceBean($serviceBean)
	{
		$this->serviceBean = $serviceBean;
	}

	/**
	 * @return string
	 * @return \common\service\CommonService
	 */
	protected function getServiceBean()
	{
		return $this->serviceBean;
	}

	//获取所有管理员
	public function getAllManagers() {
		$managerService = Beans::get('admin.manager.service');
		$managers = $managerService->getItems();
		$managers = ArrayUtils::changeArrayKey($managers, 'id');
		$this->assign('managers', $managers);
	}

	//根据ID获取操作对象
	protected function getOptobjById($id, $service=null) {
		if ( $service == null ) {
			$service = Beans::get($this->getServiceBean());
		}
		$__item = $service->getItem($id);
		if ( $__item['mobile'] ) $optObj = $__item['mobile'];
		elseif ( $__item['username'] ) $optObj = $__item['username'];
		elseif ( $__item['name'] ) $optObj = $__item['name'];
		elseif ( $__item['title'] ) $optObj = $__item['title'];

		$optObj .= " ID : {$id}";

		return $optObj;
	}

	//根据数据获取操作对象
	protected function getOptobjByData($data) {
		if ( $data['mobile'] ) $optObj = $data['mobile'];
		elseif ( $data['username'] ) $optObj = $data['username'];
		elseif ( $data['name'] ) $optObj = $data['name'];
		elseif ( $data['title'] ) $optObj = $data['title'];

		return $optObj;
	}
	//分页
	public function getPagemenu($page, $pageData)
	{

		$pagemenu = '';

		if ($pageData) {
			$pagemenu = '<ul class="pagination">';
			$pagemenu .= '<li><a href="' . $pageData['prev'] . '" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>';
			foreach ($pageData['list'] as $key => $value) {
				if ($key - $page > 4) {//省略号
					$pagemenu .= '<li><a href="javascript:void(0)">...</a></li> ';
				}
				if ($key == $page) {
					$pagemenu .= '<li class="active"><a href="#fakelink">' . $key . '</a></li> ';
				} else {
					$pagemenu .= '<li><a href="' . $value . '">' . $key . '</a></li> ';
				}
				if ($page - $key > 4) {//省略号
					$pagemenu .= '<li><a href="javascript:void(0)">...</a></li> ';
				}
			}
			$pagemenu .= '<li><a href="' . $pageData['next'] . '" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>';
			$pagemenu .= '</ul>';
		}
		return $pagemenu;

	}
}